#include"program.h"
#include"stdlib.h"
#include"interrupt.h"
#include"stdio.h"
#include"os_modules.h"
#include"thread.h"
#include"asm_utils.h"
#include"os_constant.h"
#include"tss.h"
#include"process.h"

const int PCB_SIZE = 4096;  //PCB大小4kb
char PCB_SET[PCB_SIZE*MAX_PROGRAM_AMOUNT];  //存放PCB数组
bool PCB_SET_STATUS[MAX_PROGRAM_AMOUNT];    //PCB的分配状态
int QUEUE_TICKS[MAX_QUEUE_SIZE];    //优先队列的时间片大小
int QUEUE_AGES[MAX_QUEUE_SIZE];     //优先队列饥饿时间或等待时间或年龄限制

ProgramManager::ProgramManager()
{
    initialize();
}
void ProgramManager::initialize()
{
    allPrograms.initialize();
    readyPrograms.initialize();
    running=nullptr;
    // for(int i=0; i<MAX_QUEUE_SIZE; i++)
    // {
    //     readyPrograms[i].initialize();
    // }
    for(int i=0; i<MAX_PROGRAM_AMOUNT; i++)
    {
        PCB_SET_STATUS[i]=false;
    }
    QUEUE_TICKS[MAX_QUEUE_SIZE-1]=1;
    QUEUE_AGES[MAX_QUEUE_SIZE-1]=0;
    for(int i=MAX_QUEUE_SIZE-2; i>=0; i--)
    {
        // QUEUE_TICKS[i]=10;   //极端情况可近似时间轮转
        QUEUE_TICKS[i]=QUEUE_TICKS[i+1]*2;
        QUEUE_AGES[i]=QUEUE_TICKS[i]*10;
    }
    //初始化选择子
    int selector;
    selector = asm_add_global_descriptor(USER_CODE_LOW,USER_CODE_HIGH);
    USER_CODE_SELECTOR = (selector<<3) | 0x3;

    selector = asm_add_global_descriptor(USER_DATA_LOW,USER_DATA_HIGH);
    USER_DATA_SELECTOR = (selector<<3) | 0x3;

    selector = asm_add_global_descriptor(USER_STACK_LOW,USER_STACK_HIGH);
    USER_STACK_SELECTOR = (selector<<3) | 0x3;

    initializeTSS();
}
int ProgramManager::executeThread(ThreadFunction function,void* parameter,const char* name,int priority)
{
    //关中断，防止创建线程的过程被打断
    bool status=interruptManager.getInterruptStatus();
    interruptManager.disableInterrupt();
    //分配一页作为PCB
    PCB* thread=allocatePCB();
    if(!thread)return -1;
    memset(thread,0,PCB_SIZE);
    for(int i=0; i<MAX_PROGRAM_NAME && name[i]; i++)
    {
        thread->name[i]=name[i];
    }
    thread->status=ProgramStatus::READY;
    //此处设置优先级范围，进一步可使得一个队列对应多个优先级
    if(priority>MAX_QUEUE_SIZE-1)priority=MAX_QUEUE_SIZE-1;
    else if(priority<0)priority=0;
    thread->priority=priority;
    // thread->ticks=priority*10;
    thread->ticks=QUEUE_TICKS[priority];
    thread->ticksPassedBy=0;
    thread->waits=0;
    thread->pid=((int)thread - (int)PCB_SET)/PCB_SIZE;
    //线程栈
    thread->stack=(int*)((int)thread + PCB_SIZE-sizeof(ProcessStartStack));
    thread->stack -= 7;
    thread->stack[0]=0;
    thread->stack[1]=0;
    thread->stack[2]=0;
    thread->stack[3]=0;
    thread->stack[4]=(int)function;
    thread->stack[5]=(int)program_exit;
    thread->stack[6]=(int)parameter;
    allPrograms.push_back(&(thread->tagInAllList));	
    readyPrograms.push_back(&(thread->tagInGeneralList));
    // if(!running || priority > running->priority)
    // {
    //     //优先级高则抢占,初始running空
    //     if(running)
    //     {
    //         running->status=ProgramStatus::READY;
    //         running->ticks=QUEUE_TICKS[running->priority];
    //         running->waits=0;
    //         readyPrograms[running->priority].push_back(&(running->tagInGeneralList));
    //     }
    //     thread->status=ProgramStatus::RUNNING;
    //     PCB* cur=running;
    //     running=thread;
    //     activateProgramPage(thread);
    //     asm_switch_thread(cur,thread);
    // }else{
    //     readyPrograms[priority].push_back(&(thread->tagInGeneralList));
    // }
    //恢复中断
    interruptManager.setInterruptStatus(status);
    return thread->pid;
}
PCB* ProgramManager::allocatePCB()
{
    for(int i=0; i<MAX_PROGRAM_AMOUNT; i++)
    {
        if(!PCB_SET_STATUS[i])
        {
            PCB_SET_STATUS[i]=true;
            return (PCB*)((int)PCB_SET + PCB_SIZE*i);
        }
    }
    return nullptr;
}  
void ProgramManager::releasePCB(PCB*  program)
{
    int index=((int)program- (int)PCB_SET)/PCB_SIZE;
    PCB_SET_STATUS[index]=false;
    this->allPrograms.erase(&(program->tagInAllList));
}
// void ProgramManager::schedule_multilevel_feedback_queue()
// {
//     bool status=interruptManager.getInterruptStatus();
//     interruptManager.disableInterrupt();
//     //找到下一个执行的线程
//     ListItem* item;
//     for(int i=MAX_QUEUE_SIZE-1;i>=0;i--)
//     {
//         item=readyPrograms[i].front();
//         if(item)break;
//     }
//     if(!item)//队列无线程
//     {
//         if(running->status==ProgramStatus::RUNNING)
//         {
//             running->ticks=QUEUE_TICKS[running->priority];
//             interruptManager.setInterruptStatus(status);
//             return;
//         }
//         printf("programManager halt...\n");
//         asm_halt();
//         return;
//     }
//     if(running->status==ProgramStatus::RUNNING)
//     {
//         running->status=ProgramStatus::READY;
//         if(running->priority>0)running->priority--;
//         running->ticks=QUEUE_TICKS[running->priority];
//         running->waits=0;
//         readyPrograms[running->priority].push_back(&(running->tagInGeneralList));
//     }else if(running->status==ProgramStatus::DEAD){
//         releasePCB(running);
//     }
//     PCB* next=ListItemToPCB(item,tagInGeneralList);
//     PCB* cur=running;
//     next->status=ProgramStatus::RUNNING;
//     running=next;
//     running->waits=0;
//     readyPrograms[running->priority].pop_front();
//     activateProgramPage(next);
//     asm_switch_thread(cur,next);
//     interruptManager.setInterruptStatus(status);
// }
// void ProgramManager::age()
// {
//     for(int i=MAX_QUEUE_SIZE-2; i>=0; i--)
//     {   
//         ListItem* item=readyPrograms[i].front();
//         List raisePrograms;//提高优先级的线程
//         //依次增加等待时间、年龄，达到年龄限制则升级
//         while(item)
//         {
//             PCB* cur=ListItemToPCB(item,tagInGeneralList);
//             cur->waits++;
//             if(cur->waits>=QUEUE_AGES[i])
//             {
//                 cur->waits=0;
//                 raisePrograms.push_back(item);
//                 //弹出原队列的元素
//                 readyPrograms[i].erase(item);
//                 // ListItem* temp=item;
//                 // item=item->previous;
//                 // if(temp->next)temp->next->previous=temp->previous;
//                 // temp->previous->next=temp->next;
//                 // temp->previous=temp->next=nullptr;
//             }
//             item=item->next;
//         }
//         readyPrograms[i+1].append_list(raisePrograms);
//     }
// }
void ProgramManager::schedule_round_robin()
{
    
    bool status=interruptManager.getInterruptStatus();
    interruptManager.disableInterrupt();
    if(readyPrograms.size()==0)
    {
        interruptManager.setInterruptStatus(status);
        return;
    }
    if(running->status==ProgramStatus::RUNNING)
    {
        running->status=ProgramStatus::READY;
        running->ticks=running->priority*10;
        readyPrograms.push_back(&(running->tagInGeneralList));
    }else if(running->status==ProgramStatus::DEAD){
        // 回收线程，子进程留到父进程回收
        if(!running->pageDirectoryAddress) 
        {
            releasePCB(running);
        }
        if(running->parentPid==0)
        {
            allPrograms.erase(&running->tagInAllList);
            releasePCB(running);
        }
    }
    ListItem* item=readyPrograms.front();
    
    PCB* next=ListItemToPCB(item,tagInGeneralList);
    PCB* cur=running;
    next->status=ProgramStatus::RUNNING;
    running=next;
    readyPrograms.pop_front();

    activateProgramPage(next);
    asm_switch_thread(cur,next);
    interruptManager.setInterruptStatus(status);
}
// void ProgramManager::schedule_first_in_first_out()
// {
//     if(readyPrograms.size()==0)
//     {
//         printf("halt...\n");
//         asm_halt();
//         return;
//     }
//     if(running->status==ProgramStatus::DEAD)
//     {
//         releasePCB(running);
//     }
//     ListItem* item=readyPrograms.front();
//     PCB* next=ListItemToPCB(item,tagInGeneralList);
//     PCB* cur=running;
//     next->status=ProgramStatus::RUNNING;
//     running=next;
//     readyPrograms.pop_front();
//     activateProgramPage(next);
//     asm_switch_thread(cur,next);
// }
void ProgramManager::MESA_WakeUp(PCB* program)
{
    program->status = ProgramStatus::READY;
    readyPrograms.push_front(&(program->tagInGeneralList));

    // program->ticks = QUEUE_TICKS[program->priority];
    // program->waits = 0;
    // readyPrograms[program->priority].push_front(&(program->tagInGeneralList));//对应优先级队列
}
// void ProgramManager::Hasen_WakeUp(PCB* program)
// {
//     program->status = ProgramStatus::READY;
//     program->ticks = QUEUE_TICKS[MAX_QUEUE_SIZE-1];
//     program->waits = 0;
//     readyPrograms[MAX_QUEUE_SIZE-1].push_front(&(program->tagInGeneralList));//最高优先级，会立刻执行
// }
// void ProgramManager::Hoare_WakeUp(PCB* program)
// {
//     bool status=interruptManager.getInterruptStatus();
//     interruptManager.disableInterrupt();

//     running->status = ProgramStatus::READY;
//     // running->ticks = QUEUE_TICKS[running->priority];
//     running->waits = 0;
//     readyPrograms[MAX_QUEUE_SIZE-1].push_front(&(running->tagInGeneralList));

//     running = program;
//     running->status = ProgramStatus::RUNNING;
//     running->ticks = QUEUE_TICKS[running->priority];
//     running->waits = 0;
    
//     interruptManager.setInterruptStatus(status);
// }
void ProgramManager::initializeTSS()
{
    int size=sizeof(TSS);
    int address=(int)&tss;

    memset((char*)address,0,size);
    tss.ss0=STACK_SELECTOR; //内核态堆栈段选择子

    int low,high,limit;
    limit=size-1;
    low=(address<<16)|(limit&0xff);
    //DPL=0
    high=(address&0xff000000)|((address&0x00ff0000)>>16)|((limit&0xff00)<<16)|0x00008900;

    int selector=asm_add_global_descriptor(low,high);
    //RPL=0
    asm_ltr(selector<<3);	
    tss.ioMap=address+size;
}
int ProgramManager::executeProcess(const char* filename,int priority)
{
    bool status=interruptManager.getInterruptStatus();
    interruptManager.disableInterrupt();

    //在创建线程基础上创建进程PCB
    int pid=executeThread((ThreadFunction)load_process,(void*)filename,filename,priority);
    if(pid==-1)
    {
        interruptManager.setInterruptStatus(status);
        return -1;
    }
    //找到刚刚创建的PCB,使用pid查找
    // PCB* process=ListItemToPCB(allPrograms.back(),tagInAllList); 
    PCB* process=findProgramByPid(pid);
    //创建进程页目录表
    process->pageDirectoryAddress=createProcessPageDirectory();
    if(!process->pageDirectoryAddress)
    {
        process->status=ProgramStatus::DEAD;
        interruptManager.setInterruptStatus(status);
        return -1;
    }

    //创建进程虚拟池
    bool res=createUserVirtualPool(process);
    if(!res)
    {
        process->status=ProgramStatus::DEAD;
        interruptManager.setInterruptStatus(status);
        return -1;
    }
    interruptManager.setInterruptStatus(status);
    return pid;
}
int ProgramManager::createProcessPageDirectory()
{
    //从内核地址池中分配一页存储用户进程的页目录表
    int vaddress=memoryManager.allocatePages(AddressPoolType::KERNEL,1);
    if(!vaddress)
    {
        printf("can't create page from kernel...\n");
        return 0;
    }
    memset((char*)vaddress,0,PAGE_SIZE);

    //复制内核目录项到虚拟地址的高1GB
    int* src=(int*)(0xfffff000+0x300*4);
    int* dst=(int*)(vaddress+0x300*4);
    for(int i=0;i<256;i++)
    {
        dst[i]=src[i];
    }
    //用户进程页目录表最后一项指向用户进程页目录表本身
    ((int*)vaddress)[1023]=memoryManager.virtualAddressToPhysicalAddress(vaddress)|0x7;
    return vaddress;
}
bool ProgramManager::createUserVirtualPool(PCB* process)
{
    int sourcesCount = (0xc0000000-USER_VADDR_START)/PAGE_SIZE;
    int bitmapLength=ceil(sourcesCount,8);
    //计算位图所占的页数
    int pagesCount=ceil(bitmapLength,PAGE_SIZE);
    int start=memoryManager.allocatePages(AddressPoolType::KERNEL,pagesCount);
    if(!start)
    {
        return false;
    }
    memset((char*)start,0,PAGE_SIZE*pagesCount);
    (process->userVirtual).initialize((char*)start,bitmapLength,USER_VADDR_START);
    return true;
}
void ProgramManager::activateProgramPage(PCB* program)
{
    int paddress=PAGE_DIRECTORY;
    if(program->pageDirectoryAddress)
    {
        tss.esp0=(int)program+PAGE_SIZE;
        paddress=memoryManager.virtualAddressToPhysicalAddress(program->pageDirectoryAddress);
    }
    asm_update_cr3(paddress);
}
void program_exit()
{
    PCB* thread=programManager.running;
    thread->status=ProgramStatus::DEAD;
    // programManager.schedule_multilevel_feedback_queue();
    // programManager.schedule_first_in_first_out();
    if(thread->pid)
    {
        programManager.schedule_round_robin();
    }else{
        interruptManager.disableInterrupt();
        printf("halt...\n");
        asm_halt();
    }
}
void load_process(const char* filename)
{
    interruptManager.disableInterrupt();

    PCB* process=programManager.running;
    ProcessStartStack* interruptStack = (ProcessStartStack*)((int)process+PAGE_SIZE-sizeof(ProcessStartStack));
    interruptStack->edi=0;
    interruptStack->esi=0;
    interruptStack->ebp=0;
    interruptStack->esp_dummy=0;
    interruptStack->ebx=0;
    interruptStack->edx=0;
    interruptStack->ecx=0;
    interruptStack->eax=0;
    interruptStack->gs=0;

    interruptStack->fs=programManager.USER_DATA_SELECTOR;  
    interruptStack->es=programManager.USER_DATA_SELECTOR;
    interruptStack->ds=programManager.USER_DATA_SELECTOR;

    interruptStack->eip=(int)filename;
    interruptStack->cs=programManager.USER_CODE_SELECTOR;   //用户模式平坦模式
  
    interruptStack->eflags=(0<<12)|(1<<9)|(1<<1);   //IOPL，IF=1开中断，MBS=1默认

    interruptStack->esp=memoryManager.allocatePages(AddressPoolType::USER,1);
    if(interruptStack->esp==0)
    {
        printf("can't build process!\n");
        process->status=ProgramStatus::DEAD;
        asm_halt();
    }
    interruptStack->esp += PAGE_SIZE;

    // 设置进程返回地址
    int *userStack = (int *)interruptStack->esp;
    userStack -= 3;
    userStack[0] = (int)exit;
    userStack[1] = 0;
    userStack[2] = 0;
    interruptStack->esp = (int)userStack;

    interruptStack->ss=programManager.USER_STACK_SELECTOR;

    asm_start_process((int)interruptStack);
}
int ProgramManager::fork()
{
    bool status = interruptManager.getInterruptStatus();
    interruptManager.disableInterrupt();

    //禁止内核线程调用
    PCB* parent=this->running;
    if(!parent->pageDirectoryAddress)
    {
        interruptManager.setInterruptStatus(status);
        return -1;
    }

    //创建子进程
    int pid=executeProcess("",0);
    if(pid==-1)
    {
        interruptManager.setInterruptStatus(status);
        return -1;
    }

    //初始化子进程
    PCB* child=ListItemToPCB(this->allPrograms.back(),tagInAllList);
    bool flag=copyProcess(parent,child);
    if(!flag)
    {
        child->status=ProgramStatus::DEAD;
        interruptManager.setInterruptStatus(status);
        return -1;
    }
    interruptManager.setInterruptStatus(status);
    return pid;
}
bool ProgramManager::copyProcess(PCB* parent,PCB* child)
{
    //复制进程0级栈
    ProcessStartStack* childpss=(ProcessStartStack*)((int)child+PAGE_SIZE-sizeof(ProcessStartStack));
    ProcessStartStack* parentpss=(ProcessStartStack*)((int)parent+PAGE_SIZE-sizeof(ProcessStartStack));
    memcpy(parentpss,childpss,sizeof(ProcessStartStack));
    //设置子进程返回值为0
    childpss->eax=0;

    //准备执行asm_switch_thread的栈的内容
    child->stack=(int*)childpss-7;
    child->stack[0]=0;
    child->stack[1]=0;
    child->stack[2]=0;
    child->stack[3]=0;
    child->stack[4]=(int)asm_start_process;
    child->stack[5]=0;              //asm_start_process返回地址
    child->stack[6]=(int)childpss;  //asm_start_process参数

    //设置子进程PCB
    child->status = ProgramStatus::READY;
    child->parentPid = parent->pid;
    child->priority = parent->priority;
    child->ticks = parent->ticks;
    child->ticksPassedBy = parent->ticksPassedBy;
    strcpy(child->name,parent->name);

    // 复制用户虚拟地址池
    int bitmapLength = parent->userVirtual.resources.length;
    int bitmapBytes = ceil(bitmapLength, 8);
    memcpy(parent->userVirtual.resources.bitmap, child->userVirtual.resources.bitmap, bitmapBytes);

    // 从内核中分配一页作为中转页
    char *buffer = (char *)memoryManager.allocatePages(AddressPoolType::KERNEL, 1);
    if (!buffer)
    {
        child->status = ProgramStatus::DEAD;
        return false;
    }

    // 子进程页目录表物理地址
    int childPageDirPaddr = memoryManager.virtualAddressToPhysicalAddress(child->pageDirectoryAddress);
    // 父进程页目录表物理地址
    int parentPageDirPaddr = memoryManager.virtualAddressToPhysicalAddress(parent->pageDirectoryAddress);
    // 子进程页目录表指针(虚拟地址)
    int *childPageDir = (int *)child->pageDirectoryAddress;
    // 父进程页目录表指针(虚拟地址)
    int *parentPageDir = (int *)parent->pageDirectoryAddress;

    // 子进程页目录表初始化
    memset((void *)child->pageDirectoryAddress, 0, 768 * 4);

    // 复制页目录表
    for (int i = 0; i < 768; ++i)
    {
        // 无对应页表
        if (!(parentPageDir[i] & 0x1))
        {
            continue;
        }

        // 从用户物理地址池中分配一页，作为子进程的页目录项指向的页表
        int paddr = memoryManager.allocatePhysicalPages(AddressPoolType::USER, 1);
        if (!paddr)
        {
            child->status = ProgramStatus::DEAD;
            return false;
        }
        // 页目录项
        int pde = parentPageDir[i];
        // 构造页表的起始虚拟地址
        int *pageTableVaddr = (int *)(0xffc00000 + (i << 12));

        asm_update_cr3(childPageDirPaddr); // 进入子进程虚拟地址空间

        childPageDir[i] = (pde & 0x00000fff) | paddr;
        memset(pageTableVaddr, 0, PAGE_SIZE);

        asm_update_cr3(parentPageDirPaddr); // 回到父进程虚拟地址空间
    }

    // 复制页表和物理页
    for (int i = 0; i < 768; ++i)
    {
        // 无对应页表
        if (!(parentPageDir[i] & 0x1))
        {
            continue;
        }

        // 计算页表的虚拟地址
        int *pageTableVaddr = (int *)(0xffc00000 + (i << 12));

        // 复制物理页
        for (int j = 0; j < 1024; ++j)
        {
            // 无对应物理页
            if (!(pageTableVaddr[j] & 0x1))
            {
                continue;
            }

            // 从用户物理地址池中分配一页，作为子进程的页表项指向的物理页
            int paddr = memoryManager.allocatePhysicalPages(AddressPoolType::USER, 1);
            if (!paddr)
            {
                child->status = ProgramStatus::DEAD;
                return false;
            }

            // 构造物理页的起始虚拟地址
            void *pageVaddr = (void *)((i << 22) + (j << 12));
            // 页表项
            int pte = pageTableVaddr[j];
            // 复制出父进程物理页的内容到中转页
            memcpy(pageVaddr, buffer, PAGE_SIZE);

            asm_update_cr3(childPageDirPaddr); // 进入子进程虚拟地址空间

            pageTableVaddr[j] = (pte & 0x00000fff) | paddr;
            // 从中转页中复制到子进程的物理页
            memcpy(buffer, pageVaddr, PAGE_SIZE);

            asm_update_cr3(parentPageDirPaddr); // 回到父进程虚拟地址空间
        }
    }

    // 归还从内核分配的中转页
    memoryManager.releasePages(AddressPoolType::KERNEL, (int)buffer, 1);
    return true;
}
void ProgramManager::exit(int ret)
{
    // 关中断
    interruptManager.disableInterrupt();
    
    // 第一步，标记PCB状态为DEAD并放入返回值。
    PCB *program = this->running;
    program->retValue = ret;
    program->status = ProgramStatus::DEAD;

    int *pageDir, *page;
    int paddr;

    // 第二步，如果PCB标识的是进程，则释放进程所占用的物理页、页表、页目录表和虚拟地址池bitmap的空间。
    if (program->pageDirectoryAddress)
    {
        pageDir = (int *)program->pageDirectoryAddress;
        for (int i = 0; i < 768; ++i)
        {
            if (!(pageDir[i] & 0x1))
            {
                continue;
            }

            page = (int *)(0xffc00000 + (i << 12));

            for (int j = 0; j < 1024; ++j)
            {
                if(!(page[j] & 0x1)) {
                    continue;
                }

                paddr = memoryManager.virtualAddressToPhysicalAddress((i << 22) + (j << 12));
                memoryManager.releasePhysicalPages(AddressPoolType::USER, paddr, 1);
            }

            paddr = memoryManager.virtualAddressToPhysicalAddress((int)page);
            memoryManager.releasePhysicalPages(AddressPoolType::USER, paddr, 1);
        }

        memoryManager.releasePages(AddressPoolType::KERNEL, (int)pageDir, 1);
        
        int bitmapBytes = ceil(program->userVirtual.resources.length, 8);
        int bitmapPages = ceil(bitmapBytes, PAGE_SIZE);

        memoryManager.releasePages(AddressPoolType::KERNEL, (int)program->userVirtual.resources.bitmap, bitmapPages);

    }

    int init_pid=1;
    //转移子进程到init process
    ListItem *item=allPrograms.front();
    PCB *child=ListItemToPCB(item,tagInAllList);
    while(item!=nullptr)
    {
        if(child->parentPid==program->pid)
        {
            child->parentPid=init_pid;
            printf("child pid: %d from parent %d to init %d...\n",child->pid,program->pid,init_pid);
        }
        item=item->next;
        child=ListItemToPCB(item,tagInAllList);
    }

    // 第三步，立即执行线程/进程调度。
    schedule_round_robin();
}
int ProgramManager::wait(int *retval)
{
    PCB *child;
    ListItem *item;
    bool interrupt, flag;

    while (true)
    {
        interrupt = interruptManager.getInterruptStatus();
        interruptManager.disableInterrupt();

        item = this->allPrograms.head.next;

        // 查找子进程
        flag = true;
        while (item)
        {
            child = ListItemToPCB(item, tagInAllList);
            if (child->parentPid == this->running->pid)
            {
                flag = false;
                if (child->status == ProgramStatus::DEAD)
                {
                    break;
                }
            }
            item = item->next;
        }

        if (item) // 找到一个可返回的子进程
        {
            if (retval)
            {
                *retval = child->retValue;
            }

            int pid = child->pid;
            this->allPrograms.erase(&(child->tagInAllList));
            releasePCB(child);
            interruptManager.setInterruptStatus(interrupt);
            return pid;
        }
        else 
        {
            if (flag) // 子进程已经返回
            {
                
                interruptManager.setInterruptStatus(interrupt);
                return -1;
            }
            else // 存在子进程，但子进程的状态不是DEAD
            {
                interruptManager.setInterruptStatus(interrupt);
                schedule_round_robin();
            }
        }
    }
}
PCB* ProgramManager::findProgramByPid(int pid)
{
    ListItem* item=allPrograms.front();
    PCB* process=ListItemToPCB(item,tagInAllList);
    while(item!=nullptr)
    {
        if(process->pid==pid)break;
        item=item->next;
        process=ListItemToPCB(item,tagInAllList);
    }
    if(item)
    {
        return process;
    }else{
        printf("find program pid %d failed...\n");
        return nullptr;
    }
}